/**
 * Created by bai on 2017/5/8.
 */


/**
 * TODO  地图基础功能：地图加载、底图切换、缩放、定位、图例、绘制图层
 */

var typhoonMap = {
    browser: {},
    map: {},
    currentBaseLayer: 'image',
    baseLayers: {
        image: L.layerGroup([L.tileLayer.chinaProvider('GaoDe.Satellite.Map', {
            maxZoom: 18,
            minZoom: 4
        }), L.tileLayer.chinaProvider('GaoDe.Satellite.Annotion', {
            maxZoom: 18,
            minZoom: 4
        })]),
        dixing: L.layerGroup([L.tileLayer.chinaProvider('Google.Normal.Map', {
            maxZoom: 18,
            minZoom: 4
        })]),
        normal: L.layerGroup([L.tileLayer.chinaProvider('GaoDe.Normal.Map', {
            maxZoom: 18,
            minZoom: 4
        })])
    },
    t_layers: {
        // "t_$typhoon_code":{"t_layer_group":{},"t_center_marker_layer":{},"t_path_layer":{},"t_path_point_layer":{},"t_f_path_layer":{},"t_f_path_point_layer":{}}
    },
    t_img_layer:{},
    t_c_shp_layer:{},
    // tileLayer:null,
    defZoom: 4,
    defCenter: [28.9, 128.9],
    drawn: {
        drawnItems: new L.FeatureGroup(),
        currentDrawLayer: null,
        polygon_options: {
            showArea: false,
            shapeOptions: {
                stroke: true,
                color: '#f00',
                weight: 2,
                dashArray: '5,10',
                opacity: 0.5,
                fill: true,
                fillColor: '#ff0',
                fillOpacity: 0.3,
                clickable: true
            }
        },
        onceEventListener: function (map, callback) {
            var that = this;
            // draw:created once event
            map.once('draw:created', function (e) {
                var type = e.layerType;
                that.currentDrawLayer = e.layer;
                that.drawnItems.addLayer(that.currentDrawLayer);
                // get layer data by layer type
                if (callback != null && callback != undefined) callback(e);
            });
        },
        clearDrawLayer: function (callback) {
            if (this.drawnItems) {
                this.drawnItems.clearLayers();
                //TODO do something else
                if (callback != null && callback != undefined) callback();
            }
        },
        drawPolygon: function (map, options, callback) {
            this.clearDrawLayer();
            this.onceEventListener(map, callback);
            var polygonDrawer = new L.Draw.Polygon(map, options || this.polygon_options);
            polygonDrawer.enable();
        },
        drawCircle: function (map, options, callback) {
            this.clearDrawLayer();
            this.onceEventListener(map, callback);
            var circleDrawer = new L.Draw.Circle(map, options || this.polygon_options);
            circleDrawer.enable();
        },
        drawRectangle: function (map, options, callback) {
            this.clearDrawLayer();
            this.onceEventListener(map, callback);
            var rectangleDrawer = new L.Draw.Rectangle(map, options || this.polygon_options);
            rectangleDrawer.enable();
        }
    },
    init: function (mapDiv, m) {
        this.tileLayer = this.baseLayers.dixing;
        this.map = L.map(mapDiv, {
            center: this.defCenter,
            zoom: this.defZoom,
            minZoom: 4,
            maxZoom: 18,
            maxBounds: [[-87.7, -98], [85, 283]],
            attributionControl: false,
            layers: [this.baseLayers.normal],
            zoomControl: false
        });
        this.map._attr_ = 'bjs';
        this.latlngControl();
        this.mapSourceControl();

        this.drawn.drawnItems.addTo(this.map);

    },
    /**
     * 切换底图
     * @param tileLayerName
     */
    changeTilelayer: function (tileLayerName) {
        var _map = this.map;
        var _baseLayers = this.baseLayers;
        var _currentBaseLayer = this.currentBaseLayer;
        if (tileLayerName != _currentBaseLayer) {
            $.each(_baseLayers, function (i, val) {
                if (tileLayerName != i) {
                    _map.removeLayer(val);
                } else {
                    _baseLayers[tileLayerName].addTo(_map);
                    _currentBaseLayer = i;
                }
            });
            this.currentBaseLayer = _currentBaseLayer;
        }
    },


    latlngControl: function () {
        var LatlngControl = L.Control.extend({
            initialize: function (foo, options) {
                L.Util.setOptions(this, options);
            },
            onAdd: function (map) {
                var loc = L.DomUtil.create('div', 'leaflet-control-location');
                loc.style.fontFamily = "Consolas,Arial";
                loc.style.clear = "none";
                loc.style.color = "#5195db";
                loc.innerHTML = "经度: 138.952   纬度: 28.913";
                return loc;
            }
        });
        this.map.addControl(new LatlngControl("latlngLocation", {position: 'bottomright'}));
        this.map.on("mousemove", function (e) {
            $(".leaflet-control-location").html("经度: " + Number(e.latlng.lng).toFixed(3) + "   纬度: " + Number(e.latlng.lat).toFixed(3));
        });
    },


    mapSourceControl: function () {
        var MapSourceControl = L.Control.extend({
            initialize: function (foo, options) {
                L.Util.setOptions(this, options);
            },
            onAdd: function (map) {
                var loc = L.DomUtil.create('div', 'leaflet-control-mapsource');
                loc.style.fontFamily = "Consolas,Arial";
                loc.style.clear = "none";
                loc.style.color = "#5195db";
                loc.innerHTML = "地图数据 &copy;AutoNavi";

                return loc;
            }
        });
        this.map.addControl(new MapSourceControl("mapSource", {position: 'bottomright'}));
    },



    addClickLatlng: function (e) {
        //当前点
        var clickLocation = [e.latlng.lat, e.latlng.lng];
        poly_points.push(clickLocation);
        //显示折线
        poly_line.addLatLng(e.latlng);
        map.addLayer(poly_line);
        //var point=new L.Point(e.layerPoint.x,e.layerPoint.y);
    },

    measure: function () {
        var map = this.map;
        var layer = L.layerGroup();
        layer.addTo(this.map);
        var measurePoints = [];
        var totalDistance = 0;
        var start = false;
        var lines;
        var tempLine;
        var markers = [];
        var cc = function (e) {
            map.doubleClickZoom.disable();
            start = true;
            if (measurePoints.length > 0) {
                if (e.latlng.lat != measurePoints[measurePoints.length - 1].lat && e.latlng.lng != measurePoints[measurePoints.length - 1].lng) {
                    measurePoints.push(e.latlng);
                    if (measurePoints.length == 2) {
                        lines = new L.Polyline(measurePoints, {"color": "yellow", "weight": 1});
                        lines.addTo(layer);
                    }
                    var s = L.circleMarker(e.latlng, {color: "red"});
                    s.setRadius(1);
                    if (measurePoints.length >= 2) {
                        var d = measurePoints[measurePoints.length - 1].distanceTo(measurePoints[measurePoints.length - 2]);
                        totalDistance += d;
                        var txt = (d / 1000).toFixed(3) + "（公里）";//, className: "leaflet-label-tffq"
//						s.bindLabel(txt, {noHide: true, direction: 'right', clickable: true});
                        s.bindLabel(txt, {
                            noHide: true,
                            direction: 'right',
                            clickable: true,
                            className: "leaflet-label-tffq"
                        });
                    }
                    s.addTo(layer);
                    markers.push(s);
                    lines.setLatLngs(measurePoints);
                }
            } else {
                measurePoints.push(e.latlng);
                var s = L.circleMarker(e.latlng, {color: "red"});
                s.setRadius(1);
//				s.bindLabel("起点", {noHide: true, direction: 'right'});
                s.bindLabel("起点", {noHide: true, direction: 'right', className: "leaflet-label-tffq"});
                s.addTo(layer);
                markers.push(s);
            }

        };
        var mm = function (e) {
            if (start) {
                if (tempLine != null) {
                    layer.removeLayer(tempLine);
                }
                tempLine = new L.Polyline([measurePoints[measurePoints.length - 1], e.latlng], {
                    "color": "yellow",
                    "weight": 1
                });
                tempLine.addTo(layer);
            }
        };
        var dc = function (e) {
            if (measurePoints.length > 1) {
                if (markers.length > 1) {
                    var m = markers[markers.length - 1];
                    var lab = m.getLabel();
                    var tt = document.createTextNode(m.getLabel()._content + "  总长度：" + (totalDistance / 1000).toFixed(3) + "（公里）");
                    lab._container.innerHTML = "";
                    lab._container.appendChild(tt);
                    var span = document.createElement("span");
                    span.innerHTML = "【关闭】";
                    span.style.color = "#00ff40";
                    lab._container.appendChild(span);
                    L.DomEvent.addListener(span, "click", function () {
                        map.removeLayer(layer);
                    });
                }
                start = false;
                map.off("click", cc).off("mousemove", mm).off("dblclick", dc);
                $(".tool_measure").removeAttr("id");
            }
        };
        var mu = function (e) {
            map.doubleClickZoom.enable();
        };
        map.on("click", cc).on("mousemove", mm).on("dblclick", dc).on("mouseup", mu);
        this.cancelMeasure = function () {
            map.off("click", cc).off("mousemove", mm).off("dblclick", dc).off("mouseup", mu);
        };
    },
    cancelMeasure: function () {
    },

    zoomIn: function () {
        var z = this.map.getZoom();
        this.map.setZoom(++z);
    },
    zoomOut: function () {
        var z = this.map.getZoom();
        this.map.setZoom(--z);
    },
    lineStringsIntersect: function (l1, l2) {
        var intersects = [];
        for (var i = 0; i <= l1.coordinates.length - 2; ++i) {
            for (var j = 0; j <= l2.coordinates.length - 2; ++j) {
                var a1Latlon = L.latLng(l1.coordinates[i][1], l1.coordinates[i][0]),
                    a2Latlon = L.latLng(l1.coordinates[i + 1][1], l1.coordinates[i + 1][0]),
                    b1Latlon = L.latLng(l2.coordinates[j][1], l2.coordinates[j][0]),
                    b2Latlon = L.latLng(l2.coordinates[j + 1][1], l2.coordinates[j + 1][0]),
                    a1 = L.Projection.SphericalMercator.project(a1Latlon),
                    a2 = L.Projection.SphericalMercator.project(a2Latlon),
                    b1 = L.Projection.SphericalMercator.project(b1Latlon),
                    b2 = L.Projection.SphericalMercator.project(b2Latlon),
                    ua_t = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x),
                    ub_t = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x),
                    u_b = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y);
                if (u_b != 0) {
                    var ua = ua_t / u_b,
                        ub = ub_t / u_b;
                    if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) {
                        var pt_x = a1.x + ua * (a2.x - a1.x),
                            pt_y = a1.y + ua * (a2.y - a1.y),
                            pt_xy = {
                                "x": pt_x,
                                "y": pt_y
                            },
                            pt_latlon = L.Projection.SphericalMercator.unproject(pt_xy);
                        intersects.push({
                            'type': 'Point',
                            'coordinates': [pt_latlon.lng, pt_latlon.lat]
                        });
                    }
                }
            }
        }
        if (intersects.length == 0) intersects = false;
        return intersects;
    },
    lineify: function (inputGeom) {
        var outputLines = {
            "type": "GeometryCollection",
            "geometries": []
        }
        switch (inputGeom.type) {
            case "GeometryCollection":
                for (var i in inputGeom.geometries) {
                    var geomLines = this.lineify(inputGeom.geometries[i]);
                    if (geomLines) {
                        for (var j in geomLines.geometries) {
                            outputLines.geometries.push(geomLines.geometries[j]);
                        }
                    } else {
                        outputLines = false;
                    }
                }
                break;
            case "Feature":
                var geomLines = this.lineify(inputGeom.geometry);
                if (geomLines) {
                    for (var j in geomLines.geometries) {
                        outputLines.geometries.push(geomLines.geometries[j]);
                    }
                } else {
                    outputLines = false;
                }
                break;
            case "FeatureCollection":
                for (var i in inputGeom.features) {
                    var geomLines = this.lineify(inputGeom.features[i].geometry);
                    if (geomLines) {
                        for (var j in geomLines.geometries) {
                            outputLines.geometries.push(geomLines.geometries[j]);
                        }
                    } else {
                        outputLines = false;
                    }
                }
                break;
            case "LineString":
                outputLines.geometries.push(inputGeom);
                break;
            case "MultiLineString":
            case "Polygon":
                for (var i in inputGeom.coordinates) {
                    outputLines.geometries.push({
                        "type": "LineString",
                        "coordinates": inputGeom.coordinates[i]
                    });
                }
                break;
            case "MultiPolygon":
                for (var i in inputGeom.coordinates) {
                    for (var j in inputGeom.coordinates[i]) {
                        outputLines.geometries.push({
                            "type": "LineString",
                            "coordinates": inputGeom.coordinates[i][j]
                        });
                    }
                }
                break;
            default:
                outputLines = false;
        }
        return outputLines;
    },
    crossCheck: function (baseLayer, drawLayer) {
        var baseJson = baseLayer.toGeoJSON(),
            drawJson = drawLayer.toGeoJSON(),
            baseLines = this.lineify(baseJson),
            drawLines = this.lineify(drawJson),
            crossPoints = {
                type: "GeometryCollection",
                geometries: []
            };
        if (baseLines && drawLines) {
            for (var i in drawLines.geometries) {
                for (var j in baseLines.geometries) {
                    var crossTest = this.lineStringsIntersect(drawLines.geometries[i], baseLines.geometries[j]);
                    if (crossTest) {
                        for (var k in crossTest) {
                            crossPoints.geometries.push(crossTest[k]);
                        }
                    }
                }
            }
        }
        return crossPoints;
    }

    
};

